home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK2.toast / Development Kits (Disc 2) / ScriptX / Code Samples / digtlclk / digtlclk.sx next >
Encoding:
Text File  |  1996-05-21  |  14.7 KB  |  412 lines  |  [TEXT/ttxt]

  1. in module DigitalClockModule
  2.  
  3. --*******************************************************************************
  4. --*        Class name:    DigitalClock
  5. --*                                            
  6. --*     Inherits from: TextPresenter                                    
  7. --*        Class type: Concrete
  8. --*         Component: User Interface
  9. --*
  10. --*       Description: This is a subclass of TextPresenter whose target string has
  11. --*                    the format "hour:minute:second AM/PM". It can display either 
  12. --*                    standard ("01:49:22 PM") or military time ("13:49:22:54").
  13. --*                    The setTime method allows you to toggle between the two
  14. --*                    by specifying the format.  To start the clock, call the 
  15. --*                    startClock method. It sets the time then starts callbacks 
  16. --*                    which updates the clock. The tick substring of the target 
  17. --*                    string gets updated every 60th of a second.  The second, 
  18. --*                    minute and hour substrings get updated every second, on the
  19. --*                    minute and on the hour respectively. The mode IV
  20. --*                    allows you to toggle between the clock and stopwatch modes.  
  21. --*                    To start, stop and reset the stopwatch, call the start, stop 
  22. --*                    and reset methods respectively.
  23. --*
  24. --*             Usage: dc := new DigitalClock format:@12hour
  25. --*
  26. --*               IVs:    clock
  27. --*                    format        -- format of the time display (@12hour, @24hour)
  28. --*                    _mode        -- mode of the clock (@clock, @stopwatch)    
  29. --*
  30. --*           Methods:    setHours
  31. --*                    setMinutes
  32. --*                    setSeconds
  33. --*                    setTicks
  34. --*                    setTime
  35. --*                    reset
  36. --*                    start
  37. --*                    stop
  38. --*                    modeGetter
  39. --*                    modeSetter
  40. --*                    updateClock
  41. --*                    startClock
  42. --*                    init
  43. --*                    
  44. --*    Required files:    none
  45. --*                    
  46. --*             Notes: If using text attributes other than the default, you 
  47. --*                    must explicitly set the text presenters boundary and
  48. --*                    leading (if using a different font size).
  49. --*
  50. --*            Author:    Su Quek - Kaleida Labs, Inc.
  51. --*******************************************************************************
  52. class DigitalClock (TextPresenter)
  53. inst vars
  54.     clock    : (new Clock scale:60)
  55.     format                
  56.     _mode
  57. end
  58.  
  59. --*=============================================================================*
  60. --*       Method name:    setHours
  61. --*             Class:    DigitalClock
  62. --*             Usage: setHours self
  63. --*-----------------------------------------------------------------------------*
  64. --*       Description: Determines the appropriate AM/PM and hour based on the time
  65. --*                    and format and sets their respective substrings within the
  66. --*                    target string.
  67. --*=============================================================================*
  68. method setHours self {class DigitalClock} ->
  69. (
  70.     local theString := self.target
  71.     local theHour := self.clock.time.hours
  72.     local hourString
  73.     local amPMString
  74.     
  75.     --*=========================================================================*
  76.     --* Determine the hour and AM/PM based on the time and format.
  77.     --*=========================================================================*
  78.     if (self.format = @12hour) then
  79.     (
  80.         if (theHour < 12) then
  81.             amPMString := " AM"
  82.         else
  83.             amPMString := " PM"
  84.             
  85.         theHour := mod theHour 12
  86.         if (theHour = 0) do
  87.             theHour := 12
  88.     )
  89.     else
  90.         amPMString := "   "
  91.         
  92.     --*=========================================================================*
  93.     --* Update the AM/PM substring by replacing its value within the target   
  94.        --* string.
  95.     --*=========================================================================*
  96.     deleteFromTo theString 8 11
  97.     insertAt theString amPMString 8
  98.     
  99.     --*=========================================================================*
  100.     --* Add a zero to the hour string if time is before 10:00 AM (eg 09:xx:xx AM)
  101.     --*=========================================================================*
  102.     if (theHour < 10) then
  103.         hourString := "0" + (theHour as string)
  104.     else
  105.         hourString := theHour as string
  106.     
  107.     --*=========================================================================*
  108.     --* Update the hour substring by replacing its value within the target 
  109.        --* string.
  110.     --*=========================================================================*
  111.     deleteFromTo theString 0 2
  112.     insertAt theString hourString 0
  113.     
  114.     return theHour
  115. )
  116.  
  117. --*=============================================================================*
  118. --*       Method name:    setMinutes
  119. --*             Class:    DigitalClock
  120. --*             Usage: setMinutes self
  121. --*-----------------------------------------------------------------------------*
  122. --*       Description: Sets the minute substring within the target string.
  123. --*=============================================================================*
  124. method setMinutes self {class DigitalClock} ->
  125. (
  126.     local theString := self.target
  127.     local theMin := self.clock.time.minutes
  128.     local minString
  129.                 
  130.     --*=========================================================================*
  131.     --* Add a zero to the minute string if minute < 10 (eg xx:09:xx:xx)
  132.     --*=========================================================================*
  133.     if (theMin < 10) then
  134.         minString := "0" + (theMin as string)
  135.     else
  136.         minString := theMin as string
  137.  
  138.     --*=========================================================================*
  139.     --* Update the minute substring by replacing its value within the target 
  140.     --* string.
  141.     --*=========================================================================*
  142.     deleteFromTo theString 3 5
  143.     insertAt theString minString 3
  144.     
  145.     return theMin
  146. )
  147.  
  148. --*=============================================================================*
  149. --*       Method name:    setSeconds
  150. --*             Class:    DigitalClock
  151. --*             Usage: setSeconds self
  152. --*-----------------------------------------------------------------------------*
  153. --*       Description: Sets the second substring within the target string.
  154. --*=============================================================================*
  155. method setSeconds self {class DigitalClock} ->
  156. (
  157.     local theString := self.target
  158.     local theSec := self.clock.time.seconds
  159.     local secString
  160.                 
  161.     --*=========================================================================*
  162.     --* Add a zero to the second string if second < 10 (eg xx:xx:09:xx)
  163.     --*=========================================================================*
  164.     if (theSec < 10) then
  165.         secString := "0" + (theSec as string)
  166.     else
  167.         secString := theSec as string
  168.  
  169.     --*=========================================================================*
  170.     --* Update the second substring by replacing its value within the target 
  171.     --* string.
  172.     --*=========================================================================*
  173.     deleteFromTo theString 6 8
  174.     insertAt theString secString 6
  175.     
  176.     return theSec
  177. )
  178.  
  179. --*=============================================================================*
  180. --*       Method name:    setTicks
  181. --*             Class:    DigitalClock
  182. --*             Usage: setTicks self
  183. --*-----------------------------------------------------------------------------*
  184. --*       Description: Sets the tick substring within the target string.
  185. --*=============================================================================*
  186. method setTicks self {class DigitalClock} ->
  187. (
  188.     if (self.mode = @clock) do
  189.         return
  190.         
  191.     local theString := self.target
  192.     local theTick := self.clock.time.ticks
  193.     local tickString
  194.                 
  195.     --*=========================================================================*
  196.     --* Add a zero to the tick string if tick < 10 (eg xx:xx:xx:09)
  197.     --*=========================================================================*
  198.     if (theTick < 10) then
  199.         tickString := ":0" + (theTick as string)
  200.     else
  201.         tickString := ":" + (theTick as string)
  202.  
  203.     --*=========================================================================*
  204.     --* Update the tick substring by replacing its value within the target 
  205.     --* string.
  206.     --*=========================================================================*
  207.     deleteFromTo theString 8 11
  208.     insertAt theString tickString 8
  209.     
  210.     return theTick
  211. )
  212.  
  213. --*=============================================================================*
  214. --*       Method name:    setTime
  215. --*             Class:    DigitalClock
  216. --*             Usage: setTime self timeFormat
  217. --*                        timeFormat    - NameClass object (@12hour, @24hour)
  218. --*-----------------------------------------------------------------------------*
  219. --*       Description: Changes the format IV and then sets the hour, minute, second 
  220. --*                    and tick substrings of the target string to the calendar 
  221. --*                    clock's time.
  222. --*                    Use this method to change the display format of the clock.
  223. --*=============================================================================*
  224. method setTime self {class DigitalClock} timeFormat ->
  225. (
  226.     self.format := timeFormat
  227.     
  228.     --*=========================================================================*
  229.     --* Set the clock time to the calendar clock time.
  230.     --*=========================================================================*
  231.     local calendarTime := theCalendarClock.date
  232.     local clockTime := new Time
  233.     
  234.     clockTime.hours := calendarTime.hours
  235.     clockTime.minutes := calendarTime.minutes
  236.     clockTime.seconds := calendarTime.seconds
  237.     clockTime.ticks := calendarTime.ticks
  238.  
  239.     self.clock.time := clockTime
  240.     
  241.     --*=========================================================================*
  242.     --* Set the hour, minute, second and tick substring of the target string.
  243.     --*=========================================================================*
  244.     setHours self
  245.     setMinutes self
  246.     setSeconds self
  247.     setTicks self
  248.     
  249.     --*=========================================================================*
  250.     --* Start the clock.
  251.     --*=========================================================================*
  252.     self.clock.rate := 1
  253.         
  254.     return timeFormat
  255. )
  256.  
  257. --*=============================================================================*
  258. --*       Method name:    reset
  259. --*             Class:    DigitalClock
  260. --*             Usage: reset self 
  261. --*-----------------------------------------------------------------------------*
  262. --*       Description: Stops and resets the stopwatch.
  263. --*=============================================================================*
  264. method reset self {class DigitalClock} ->
  265. (
  266.     if (self.mode = @clock) do
  267.         return
  268.         
  269.     self.format := @24hours
  270.     
  271.     --*=========================================================================*
  272.     --* Stop the clock and reset the clock time.
  273.     --*=========================================================================*
  274.     self.clock.rate := 0
  275.     self.clock.time := 0
  276.     
  277.     --*=========================================================================*
  278.     --* Set the hour, minute, second and tick substring of the target string
  279.     --*=========================================================================*
  280.     setHours self
  281.     setMinutes self
  282.     setSeconds self
  283.     setTicks self
  284.     
  285.     return 
  286. )
  287.  
  288. --*=============================================================================*
  289. --*       Method name:    start
  290. --*             Class:    DigitalClock
  291. --*             Usage: start self 
  292. --*-----------------------------------------------------------------------------*
  293. --*       Description: Starts the stopwatch.
  294. --*=============================================================================*
  295. method start self {class DigitalClock} ->
  296. (
  297.     if (self.mode = @stopwatch) do
  298.         self.clock.rate := 1
  299. )
  300.  
  301. --*=============================================================================*
  302. --*       Method name:    stop
  303. --*             Class:    DigitalClock
  304. --*             Usage: stop self 
  305. --*-----------------------------------------------------------------------------*
  306. --*       Description: Stop the stopwatch.
  307. --*=============================================================================*
  308. method stop self {class DigitalClock} ->
  309. (
  310.     if (self.mode = @stopwatch) do
  311.         self.clock.rate := 0
  312. )
  313.  
  314. --*=============================================================================*
  315. --*       Method name:    modeGetter
  316. --*             Class:    DigitalClock
  317. --*             Usage: modeGetter self
  318. --*-----------------------------------------------------------------------------*
  319. --*       Description: Returns the mode (@clock, @stopwatch).
  320. --*=============================================================================*
  321. method modeGetter self {class DigitalClock} ->
  322. (
  323.     return self._mode
  324. )
  325.  
  326. --*=============================================================================*
  327. --*       Method name:    modeSetter
  328. --*             Class:    DigitalClock
  329. --*             Usage: modeSetter self value
  330. --*                        value    - nameclass (@clock, @stopwatch)
  331. --*-----------------------------------------------------------------------------*
  332. --*       Description: Sets the mode to either @clock or @stopwatch.
  333. --*=============================================================================*
  334. method modeSetter self {class DigitalClock} value ->
  335. (    
  336.     self._mode := value
  337.  
  338.     if (value = @stopwatch) then
  339.         reset self
  340.     else
  341.         setTime self self.format
  342.             
  343.     return value
  344. )
  345.  
  346. --*=============================================================================*
  347. --*       Method name:    updateClock
  348. --*             Class:    DigitalClock
  349. --*             Usage: updateClock self 
  350. --*-----------------------------------------------------------------------------*
  351. --*       Description: Updates the hour, minute and second substrings of the 
  352. --*                    target string. The second, minute and hour substrings gets 
  353. --*                    updated every second, on the minute and on the hour 
  354. --*                    respectively.
  355. --*=============================================================================*
  356. method updateClock self {class DigitalClock} ->
  357. (
  358.     if ((setSeconds self) = 0) do
  359.         if ((setMinutes self) = 0) do
  360.             setHours self
  361.  
  362.     return self.target
  363. )
  364.             
  365. --*=============================================================================*
  366. --*       Method name:    startClock
  367. --*             Class:    DigitalClock
  368. --*             Usage: startClock self 
  369. --*-----------------------------------------------------------------------------*
  370. --*       Description: Sets the time then starts callbacks which update the clock
  371. --*                    every second and the ticks every 60th of a second
  372. --*=============================================================================*
  373. method startClock self {class DigitalClock} ->
  374. (
  375.     if (self.mode = @clock) do
  376.         setTime self self.format
  377.         
  378.     addPeriodicCallback self.clock updateClock self #() 60
  379.     addPeriodicCallback self.clock setTicks self #() 1
  380. )
  381.  
  382. --*=============================================================================*
  383. --*       Method name:    init
  384. --*             Class:    DigitalClock
  385. --*             Usage: init self [boundary:<Stencil>]
  386. --*                              [format:<NameClass>]        - (@12hour, @24hour)
  387. --*                              [mode:<NameClass>]        - (@clock, @stopwatch)
  388. --*-----------------------------------------------------------------------------*
  389. --*       Description: Creates and initializes the TextPresenter to its default
  390. --*                    values unless another is explicitly given.
  391. --*                    Default values: 
  392. --*                        boundary - (new rect x2:94 y2:20)
  393. --*                        target     - (new String string:"00:00:00:00")
  394. --*                        format     - (@24hour)
  395. --*                        mode     - (@clock)
  396. --*=============================================================================*
  397. method init self {class DigitalClock} #rest args \
  398.                                       #key boundary:(new rect x2:94 y2:20) \
  399.                                              format:(@24hour) \
  400.                                              mode:(@clock) ->
  401. (
  402.     apply nextmethod self boundary:boundary \
  403.                           target:(new String string:"00:00:00:00") args
  404.     self.isTransparent := true
  405.     
  406.     self.format := format
  407.     self.mode := mode
  408.     
  409.     self
  410. )
  411.  
  412.